/*
 *  libKara - Library for basic instant messaging functions
 *  Copyright (C) 2007 Markus Karnik
 *
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 3 of the License, 
 *  or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along 
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 *  
 */

package de.karnik.libkara.proto.xmpp;

import java.io.BufferedWriter;
import java.io.IOException;

import de.karnik.libkara.proto.xmpp.packages.XmlPackage;
import de.karnik.libkara.proto.xmpp.packages.XmlPackageStorage;

/**
 * Reads and writes every output package from the given package storage to the given XmppBufferedWriter.
 * 
 * @author Markus Karnik - markus.karnik@my-design.org
 * @version 1.0
 * @since 1.0
 */
public class XmppWriterThread extends Thread {

	/**
	 * Indicates if current thread is running.
	 */
	private boolean running = false;
	/**
	 * The package storage to read from.
	 */
	private XmlPackageStorage packageStorage = null;
	/**
	 * The XmppBufferedWriter to write to.
	 */
	private BufferedWriter xmppWriter = null;
	/**
	 * The thread listener for callbacks.
	 */
	private XmppThreadListener threadListener = null; 
	/**
	 * The unique thread id.
	 */
	private String threadID = "standard";
	
	/**
	 * Basic constructor to create and configure the thread.
	 * 
	 * @param threadID The unique threadID.
	 * @param xmppWriter The XmppBufferedWriter to write to.
	 * @param packageStorage The package storage to read from.
	 */
	public XmppWriterThread( String threadID, BufferedWriter xmppWriter, XmlPackageStorage packageStorage ) {
		super();
		this.threadID = threadID;
		this.xmppWriter = xmppWriter;
		this.packageStorage = packageStorage;
	}
	
	/**
	 * Overrides the old XmppBufferedWriter with the given one.
	 * 
	 * @param xmppWriter The overriding XmppBufferedWriter.
	 */
	public void refreshXmppWriter( BufferedWriter xmppWriter ) {
		this.xmppWriter = xmppWriter;
	}
	
	/**
	 * Removes the current XmppThreadListener.
	 */
	public void removeThreadListener() {
		this.threadListener = null;
	}

	/**
	 * Sets the current XmppThreadListener.
	 * 
	 * @param threadListener The XmppThreadListener for thread callbacks.
	 */
	public void setThreadListener( XmppThreadListener threadListener ) {
		this.threadListener = threadListener;
	}
	
	/**
	 * Shuts down the current thread.
	 */
	public void shutdown() {
		this.running = false;
		this.packageStorage.interruptOutput();
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	public void run() {
		
		// create temp vars
		XmlPackage xmlPackage = null;
		this.running = true;
		
		// send started to the listener
		if( this.threadListener != null )
			this.threadListener.threadStarted( this.threadID );
		
		// while the thread is running an a package storage is available 
		while( this.running && ( this.packageStorage != null ) ) {
			xmlPackage = null;
			
			try {
				// read next output package
				xmlPackage = this.packageStorage.getNextOutputPackage();
			} catch ( InterruptedException e ) {
				// send interrupted to the listener
				if( this.threadListener != null )
					this.threadListener.threadInterrupted( this.threadID );				
			}
			
			try {
				// write the next output package
				if( xmlPackage != null ) {
					xmppWriter.write( xmlPackage.getXmlSource() + "\n" );
					xmppWriter.flush();
				}
			// stop the thread on I/O error
			} catch ( IOException e ) {
				this.shutdown();
			}	
			
		}
		// send stop signal to the listener
		if( this.threadListener != null )
			this.threadListener.threadStopped( this.threadID );
	}
}
